package org.example;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class MultiThreadNestingDemo {

    //连接池配置
    private static final int OUTER_THREAD_NUM = 2;
    private static final int THREAD_POOL_SIZE = 10;

    public static void main(String[] args) {
        // 模拟查询数据到 List<String> dataList
        List<String> dataList = Arrays.asList("data1", "data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9", "data10", "data11", "data12", "data13", "data14");

        // 将数据分成若干批次，每批次10个数据
        List<List<String>> dataBatchList = dataList.stream().collect(Collectors.groupingBy(data -> dataList.indexOf(data) / 10)).values().stream().collect(Collectors.toList());

        // 外部多线程异步处理每个批次的数据
        int innerThreadNum = 5;
        ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
        ExecutorService innerThreadPool = Executors.newFixedThreadPool(innerThreadNum);
        CountDownLatch latch = new CountDownLatch(dataBatchList.size());
        for (int i = 0; i < OUTER_THREAD_NUM; i++) {
            Connection conn = getConnection("db", "root", "123456");
            threadPool.submit(() -> {
                try {
                    for (List<String> dataBatch : dataBatchList) {

                        CountDownLatch innerLatch = new CountDownLatch(dataBatch.size());
                        for (String data : dataBatch) {
                            innerThreadPool.submit(() -> {
                                try {
                                    // 处理内部任务，写入数据库
                                    process(conn, data);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                } finally {
                                    innerLatch.countDown();
                                }
                            });
                        }
                        innerLatch.await(); // 等待批次内部任务全部结束才进入下一个批次
                        innerThreadPool.shutdown();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        conn.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    latch.countDown();
                }
            });
        }

        // 等待所有线程全部执行完毕再继续进行
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        threadPool.shutdown();
    }

    /**
     * 获取 JDBC 连接对象
     * @param dbName 数据库名称
     * @param userName 数据库登录用户名
     * @param password 数据库登录密码
     * @return Connection 数据库连接对象
     */
    private static Connection getConnection(String dbName, String userName, String password) {
        Connection conn = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 连接代码实现
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + dbName + "?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true", userName, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 内部线程处理逻辑
     *
     * @param conn 数据库连接对象
     * @param data 数据内容
     */
    private static void process(Connection conn, String data) {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + "：开始处理数据 " + data);

        // 执行 SQL
        try {
            String sql = "INSERT INTO table_name(data) VALUES (?)";
            conn.prepareStatement(sql).executeUpdate();
            // 其他 SQL 处理逻辑...
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}